/**
 * @author Ahammer
 * @date 2009 06
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package opgui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollBar;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import main.IqmTools;
import main.Manager;
import main.Tank;

public class IqmHistoModifyGUI  extends IqmOperatorJFrame
							    implements IqmOperatorGUIBuilder, ActionListener, AdjustmentListener {

	private  ParameterBlockJAI pb = null;  //  @jve:decl-index=0:
		
	private int offSetLow, offSetHigh;  //Offset for lowest  and highest grey value 
	
	private  JPanel 	jScrollBarPanelOffSetLow    = null;
	private  JScrollBar	jScrollBarOffSetLow         = null;
	private  JLabel     jLabelOffSetLow;
	
	private  JPanel 	jScrollBarPanelOffSetHigh   = null;
	private  JScrollBar	jScrollBarOffSetHigh        = null;
	private  JLabel     jLabelOffSetHigh;
	
	private static 	JCheckBox jCheckBoxBandCombine  = null;	
		
	private  JRadioButtonMenuItem buttMethodRescale = null;
	private  JRadioButtonMenuItem buttMethodEqual	= null;
	private  JRadioButtonMenuItem buttMethodNorm	= null;
	private  JRadioButtonMenuItem buttMethodPiece   = null;
	private  JRadioButtonMenuItem buttMethodHidden	= null;
	private  JLabel 			  jLabelMethodText	= null;
	private  JToolBar 			  jToolBarMethod  	= null;
	private  ButtonGroup 		  buttGroupMethod 	= null;
	
	private  JButton              jButtonHistoOld    = null; 
	private  JButton              jButtonHistoNew    = null; 

		
	/**
	 * constructor
	 */
	public IqmHistoModifyGUI() {

	}


	/**
	 * This method sets the current parameter block to the argument
	 * @param ParameterBlockJAI pb
	 *
	 */
	@Override
	public void setParameterBlock(ParameterBlockJAI arg){
		pb = arg;
		IqmTools.setCurrParameterBlockJAI(pb);	
	}
	/**
	 * This method sets the current parameter block
	 * The individual values of the GUI current ParameterBlock
	 *
	 */
	@Override
	public void setParameterBlock(){
		pb.setParameter("OffSetLow",  offSetLow);
		pb.setParameter("OffSetHigh", offSetHigh);
		if (jCheckBoxBandCombine.isSelected())  pb.setParameter("BandCombine", 1);
		if (!jCheckBoxBandCombine.isSelected()) pb.setParameter("BandCombine", 0);
	
		if (buttMethodRescale.isSelected()) pb.setParameter("Method", 0);
		if (buttMethodEqual.isSelected())   pb.setParameter("Method", 1);
		if (buttMethodNorm.isSelected())    pb.setParameter("Method", 2);
		if (buttMethodPiece.isSelected())   pb.setParameter("Method", 3);

	
		IqmTools.setCurrParameterBlockJAI(pb);	
	}
	
	/**
	 * This method sets the current parameter values
	 */
	@Override
	public void setParameterValues(){
		int idx = IqmTools.getCurrManagerImgIndex();
	    PlanarImage pi = Tank.getCurrentTankImageAt(idx); 
	       if (pi == null){
	    	   System.out.println("IqmHistoModifyGUI: Current image not defined");
	    	   return;
	       }
        //String type = IqmTools.getCurrImgTyp(pi);
	       
		offSetLow  = pb.getIntParameter("OffSetLow");
		offSetHigh = pb.getIntParameter("OffSetHigh");
		
		jScrollBarOffSetLow.removeAdjustmentListener(this);
		jScrollBarOffSetLow.setValue(offSetLow);
		jScrollBarOffSetLow.addAdjustmentListener(this);
		jLabelOffSetLow.setText ("Offset low: " + (double)offSetLow + " %");
		
		jScrollBarOffSetHigh.removeAdjustmentListener(this);
		jScrollBarOffSetHigh.setValue(offSetHigh);
		jScrollBarOffSetHigh.addAdjustmentListener(this);
		jLabelOffSetHigh.setText ("Offset high: " + (double)offSetHigh + " %");
		
	    if (pb.getIntParameter("BandCombine") == 0) jCheckBoxBandCombine.setSelected(false);
	    if (pb.getIntParameter("BandCombine") == 1) jCheckBoxBandCombine.setSelected(true);
	       
		buttMethodHidden.setSelected(true);		
		if (pb.getIntParameter("Method") == 0) buttMethodRescale.setSelected(true);		
		if (pb.getIntParameter("Method") == 1) buttMethodEqual.setSelected(true);		
		if (pb.getIntParameter("Method") == 2) buttMethodNorm.setSelected(true);
		if (pb.getIntParameter("Method") == 3) buttMethodPiece.setSelected(true);	
	}
		

	/**
	 * This method creates and shows the GUI
	 */
	@Override
	public void createIqmOperatorGUI() {
		//opGUIFrame = new ImgProcFuncJFrame();  //actionPerforemd events werden in dieser Klasse abgehandelt
		//opGUIFrame = new IqmHistoModifyGUI();      //actionPerforemd events werden in dieser Klasse abgehandelt
		//this.getJContentPane();
		this.initialize(); //Aufruf von ImgProcFuncJFrame
		this.setTitle("HistoModify");
		PlanarImage pi = Tank.getCurrentTankImageAt(IqmTools.getCurrManagerImgIndex());
		//int numBands = pi.getNumBands();
		//Dimension dim = this.getSize();
		//this.setSize(dim.width, dim.height + 200);
		//this.setPreferredSize(new Dimension(800, 600));
		this.getJContentPane().add(getJScrollBarOffSetLow(),  getGridBagConstraintsOffSetLow());
		this.getJContentPane().add(getJScrollBarOffSetHigh(), getGridBagConstraintsOffSetHigh());
		this.getJContentPane().add(getJCheckBoxBandCombine(), getGridBagConstraintsBandCombine());
		this.getJContentPane().add(getJLabelMethodText(),     getGridBagConstraintsMethodText());
		this.getJContentPane().add(getJToolBarMethod(),       getGridBagConstraintsButtonGroupMethod());
		this.getJContentPane().add(getJButtonHistoOld(),      getGridBagConstraintsButtonHistoOld());
		this.getJContentPane().add(getJButtonHistoNew(),      getGridBagConstraintsButtonHistoNew());
	
		this.pack();
		//this.repaint();
		if (pb == null) pb = new ParameterBlockJAI("IqmHistoModify");  //nur wenn das erste mal aufgerufen
		//pb = new ParameterBlockJAI("IqmHistoModify"); //immer der default Block
		IqmTools.setCurrParameterBlockJAI(pb);
		setParameterValues();
	}

	//------------------------------------------------------------------------------
	private  GridBagConstraints getGridBagConstraintsOffSetLow(){
		GridBagConstraints gridBagConstraintsOffSetLow = new GridBagConstraints();
		gridBagConstraintsOffSetLow.gridx = 1;
		gridBagConstraintsOffSetLow.gridy = 4;
		gridBagConstraintsOffSetLow.gridwidth = 3;
		gridBagConstraintsOffSetLow.insets = new Insets(10,0,0,0);  //top, left bottom right
		//gridBagConstraintsOffSetLow.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsOffSetLow;
	}
	private  GridBagConstraints getGridBagConstraintsOffSetHigh(){
		GridBagConstraints gridBagConstraintsOffSetHigh = new GridBagConstraints();
		gridBagConstraintsOffSetHigh.gridx = 1;
		gridBagConstraintsOffSetHigh.gridy = 5;
		gridBagConstraintsOffSetHigh.gridwidth = 3;
		gridBagConstraintsOffSetHigh.insets = new Insets(10,0,0,0);  //top, left bottom right
		//gridBagConstraintsOffSetHigh.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsOffSetHigh;
	}
	private  GridBagConstraints getGridBagConstraintsBandCombine(){
		GridBagConstraints gridBagConstraintsBandCombine = new GridBagConstraints();
		gridBagConstraintsBandCombine.gridx = 2;
		gridBagConstraintsBandCombine.gridy = 6;
		gridBagConstraintsBandCombine.gridwidth = 2;
		gridBagConstraintsBandCombine.insets = new Insets(10,0,0,0);  //top, left bottom right
		//gridBagConstraintsBandCombine.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsBandCombine;
	}
	private  GridBagConstraints getGridBagConstraintsMethodText(){
		GridBagConstraints gridBagConstraintsMethodText = new GridBagConstraints();
		gridBagConstraintsMethodText.gridx = 1;
		gridBagConstraintsMethodText.gridy = 7;
		//gridBagConstraintsMethodText.gridwidth = 3;
		gridBagConstraintsMethodText.insets = new Insets(10,15,0,0);  //top, left bottom right
		gridBagConstraintsMethodText.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsMethodText;
	}
	private  GridBagConstraints getGridBagConstraintsButtonGroupMethod(){
		GridBagConstraints gridBagConstraintsButtonGroupMethod = new GridBagConstraints();
		gridBagConstraintsButtonGroupMethod.gridx = 2;
		gridBagConstraintsButtonGroupMethod.gridy = 7;
		gridBagConstraintsButtonGroupMethod.gridwidth = 2;
		gridBagConstraintsButtonGroupMethod.insets = new Insets(10,0,0,15);  //top, left bottom right
		gridBagConstraintsButtonGroupMethod.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonGroupMethod;
	}
	private  GridBagConstraints getGridBagConstraintsButtonHistoOld(){
		GridBagConstraints gridBagConstraintsButtonHistoOld = new GridBagConstraints();
		gridBagConstraintsButtonHistoOld.gridx = 1;
		gridBagConstraintsButtonHistoOld.gridy = 8;
		//gridBagConstraintsButtonHistoOld.gridwidth = 2;
		gridBagConstraintsButtonHistoOld.insets = new Insets(10,10,20,10);  //top, left bottom right
		gridBagConstraintsButtonHistoOld.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonHistoOld;
	}
	private  GridBagConstraints getGridBagConstraintsButtonHistoNew(){
		GridBagConstraints gridBagConstraintsButtonHistoNew = new GridBagConstraints();
		gridBagConstraintsButtonHistoNew.gridx = 2;
		gridBagConstraintsButtonHistoNew.gridy = 8;
		gridBagConstraintsButtonHistoNew.gridwidth = 2;
		gridBagConstraintsButtonHistoNew.insets = new Insets(10,10,20,40);  //top, left bottom right
		gridBagConstraintsButtonHistoNew.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonHistoNew;
	}



	//------------------------------------------------------------------------------------------------------------------
	/**
	 * This method updates the GUI if needed
	 * This method overrides IqmOperatorJFrame
	 */
	@Override
	public void updateIqmOperatorGUI(){
	
	}
	//----------------------------------------------------------------------------------------
	/**
	 * This method initializes jScrollBarOffSetLow	
	 * @return javax.swing.JScrollBar	
	 */
	private  JPanel getJScrollBarOffSetLow() {
		if (jScrollBarOffSetLow	== null) {
			jScrollBarPanelOffSetLow = new JPanel();	
			jScrollBarPanelOffSetLow.setLayout(new BorderLayout());
			jScrollBarPanelOffSetLow.setPreferredSize(new Dimension(250,18));			
			jScrollBarOffSetLow	= new JScrollBar(JScrollBar.HORIZONTAL);
			jScrollBarOffSetLow.setToolTipText("low grey level offset [%]");
			jScrollBarOffSetLow.setValues(1, 0, 0, 100);
			jScrollBarOffSetLow.setUnitIncrement(1);
			jScrollBarOffSetLow.addAdjustmentListener(this);
			jLabelOffSetLow    = new JLabel();
			jLabelOffSetLow.setText  ("Offset low: " + 0.0 + " %");
			jLabelOffSetLow.setPreferredSize(new Dimension(120,10));
			jScrollBarPanelOffSetLow.add(jLabelOffSetLow,     BorderLayout.WEST);
			jScrollBarPanelOffSetLow.add(jScrollBarOffSetLow, BorderLayout.CENTER);		
		}
		return jScrollBarPanelOffSetLow	;
	}
	/**
	 * This method initializes jScrollBarOffSetLow	
	 * @return javax.swing.JScrollBar	
	 */
	private  JPanel getJScrollBarOffSetHigh() {
		if (jScrollBarOffSetHigh	== null) {
			jScrollBarPanelOffSetHigh = new JPanel();	
			jScrollBarPanelOffSetHigh.setLayout(new BorderLayout());
			jScrollBarPanelOffSetHigh.setPreferredSize(new Dimension(250,18));			
			jScrollBarOffSetHigh	= new JScrollBar(JScrollBar.HORIZONTAL);
			jScrollBarOffSetHigh.setToolTipText("high grey level offset [%]");
			jScrollBarOffSetHigh.setValues(1, 0, 0, 100);
			jScrollBarOffSetHigh.setUnitIncrement(1);
			jScrollBarOffSetHigh.addAdjustmentListener(this);
			jLabelOffSetHigh    = new JLabel();
			jLabelOffSetHigh.setText  ("Offset high: " + 0.0 + " %");
			jLabelOffSetHigh.setPreferredSize(new Dimension(120,10));
			jScrollBarPanelOffSetHigh.add(jLabelOffSetHigh,     BorderLayout.WEST);
			jScrollBarPanelOffSetHigh.add(jScrollBarOffSetHigh, BorderLayout.CENTER);		
		}
		return jScrollBarPanelOffSetHigh	;
	}
	//--------------------------------------------------------------------------------------------
	/**
	 * This method initializes jCheckBoxBandCombine	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxBandCombine() {
		if (jCheckBoxBandCombine == null) {
			jCheckBoxBandCombine = new JCheckBox();
			//jCheckBoxBandCombine.setName("Band combine");
			jCheckBoxBandCombine.setText("Band combine");
			jCheckBoxBandCombine.setSelected(false);
			jCheckBoxBandCombine.addActionListener(this);
			jCheckBoxBandCombine.setActionCommand("parameter");
			jCheckBoxBandCombine.setEnabled(false);
		}
		return jCheckBoxBandCombine;
	}
	//-----------------------------------------------------------------------------------------
	/**
	 * This method initializes jLabelMethodText	
	 * @return javax.swing.JLabel	
	 */
	private  JLabel getJLabelMethodText() {
		if (jLabelMethodText == null) {
			jLabelMethodText = new JLabel();
			jLabelMethodText.setText("Method:");
		}
		return jLabelMethodText	;
	}
	/**
	 * This method initializes the Option: MethodRescale 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtMethodRescale() {
		//if (buttMethodRescale == null) {
			buttMethodRescale = new JRadioButtonMenuItem();
			buttMethodRescale.setText("Rescale");
			buttMethodRescale.setToolTipText("histogram rescaling");
			buttMethodRescale.addActionListener(this);
			buttMethodRescale.setActionCommand("parameter");
		//}
		return buttMethodRescale;
	}
	/**
	 * This method initializes the Option: MethodEqual
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtMethodEqual() {
		//if (buttMethodEqual == null) {
			buttMethodEqual = new JRadioButtonMenuItem();
			buttMethodEqual.setText("Equalize");
			buttMethodEqual.setToolTipText("histogram equalization");
			buttMethodEqual.addActionListener(this);
			buttMethodEqual.setActionCommand("parameter");
		//}
		return buttMethodEqual;
	}
	/**
	 * This method initializes the Option: MethodNorm
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtMethodNorm() {
		//if (buttMethodNorm == null) {
			buttMethodNorm = new JRadioButtonMenuItem();
			buttMethodNorm.setText("Normalization");
			buttMethodNorm.setToolTipText("histogram normalization");
			buttMethodNorm.addActionListener(this);
			buttMethodNorm.setActionCommand("parameter");
		//}
		return buttMethodNorm;
	}
	/**
	 * This method initializes the Option: MethodPiece
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtMethodPiece() {
		//if (buttMethodPiece == null) {
			buttMethodPiece = new JRadioButtonMenuItem();
			buttMethodPiece.setText("Piecewise");
			buttMethodPiece.setToolTipText("picewise linear mapping");
			buttMethodPiece.addActionListener(this);
			buttMethodPiece.setActionCommand("parameter");
		//}
		return buttMethodPiece;
	}

	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtMethodHidden() {
		//if (buttMethodHidden == null) {
			buttMethodHidden  = new JRadioButtonMenuItem();
			buttMethodHidden .setText("Hidden");
			buttMethodHidden.setVisible(false);

		//}
		return buttMethodHidden;
	}
	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarMethod() {
//		if (jToolBarMethod == null) {
			jToolBarMethod = new JToolBar("Options");
			jToolBarMethod.setOrientation(1); //
			jToolBarMethod.add(getJRadioButtonMenuButtMethodRescale());
			jToolBarMethod.add(getJRadioButtonMenuButtMethodEqual());			
			jToolBarMethod.add(getJRadioButtonMenuButtMethodNorm());
			jToolBarMethod.add(getJRadioButtonMenuButtMethodPiece());
			jToolBarMethod.add(getJRadioButtonMenuButtMethodHidden());

			//jToolBarRGB.addSeparator();
			this.setButtonGroupMethod();	//Gruppieren der JRadioButtons
//		}
		return jToolBarMethod;
	}
	private  void setButtonGroupMethod() {
		//if (ButtonGroup buttGroupMethod == null) {
			buttGroupMethod = new ButtonGroup();
			buttGroupMethod.add(buttMethodRescale);
			buttGroupMethod.add(buttMethodEqual);
			buttGroupMethod.add(buttMethodNorm);
			buttGroupMethod.add(buttMethodPiece);
			buttGroupMethod.add(buttMethodHidden);		
	}
	//--------------------------------------------------------------------------------------------
	/**
	 * This method initializes jButtonHistoOld	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JButton getJButtonHistoOld() {
		if (jButtonHistoOld        == null) {
			jButtonHistoOld  = new JButton();
			jButtonHistoOld.setText("Get old histogram");
			jButtonHistoOld.addActionListener(this);
			jButtonHistoOld.setActionCommand("histoold");			
		}
		return jButtonHistoOld ;
	}
	/**
	 * This method initializes jButtonHistoNew	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JButton getJButtonHistoNew() {
		if (jButtonHistoNew        == null) {
			jButtonHistoNew  = new JButton();
			jButtonHistoNew.setText("Get new histogram");
			jButtonHistoNew.addActionListener(this);
			jButtonHistoNew.setActionCommand("histonew");			
		}
		return jButtonHistoNew ;
	}

	//--------------------------------------------------------------------------------------------
	public void actionPerformed(ActionEvent e) {
		//System.out.println("IqmHistoModifyGUI: event e: " +e.getActionCommand());
		if ("reset".equals(e.getActionCommand())) {
			ParameterBlockJAI pb = new ParameterBlockJAI("IqmHistoModify".toLowerCase());
			IqmTools.setCurrParameterBlockJAI(pb);
			this.setParameterBlock(pb);
			this.setParameterValues();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
			this.reset();
		}
		if ("parameter".equals(e.getActionCommand())) {
			this.setParameterBlock();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		}
		if ("histoold".equals(e.getActionCommand())) { //button
			int index = IqmTools.getCurrManagerImgIndex();
			PlanarImage pi = Tank.getCurrentTankImageAt(index);
			IqmTools.plotHistogram(pi);
			this.setParameterBlock();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		}
		if ("histonew".equals(e.getActionCommand())) { //button			
			PlanarImage pi = Manager.getPreviewImage();
			if (pi != null) IqmTools.plotHistogram(pi);
			this.setParameterBlock();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		}

		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}

	}
	//------------------------------------------------------------------------------------------------
	@Override
	public void adjustmentValueChanged(AdjustmentEvent e) {
		Object obE = e.getSource();
		if (obE instanceof JScrollBar){		
			if (obE == jScrollBarOffSetLow){
				offSetLow = jScrollBarOffSetLow.getValue();
				jLabelOffSetLow.setText  ("Offset low: " + ((double)offSetLow/10d) + " %");
			}
			if (obE == jScrollBarOffSetHigh){
				offSetHigh = jScrollBarOffSetHigh.getValue();
				jLabelOffSetHigh.setText  ("Offset high: " + ((double)offSetHigh/10d) + "%");
			}
			if ((offSetLow > 0) || (offSetHigh > 0)){
				jCheckBoxBandCombine.setEnabled(true);
			} else{
				jCheckBoxBandCombine.setEnabled(false);
			}
		}
		this.setParameterBlock();
		//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}
	}

	//-------------------------------------------------------------------------------------------------
	public static void main() {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				IqmHistoModifyGUI gui = new IqmHistoModifyGUI();
				gui.createIqmOperatorGUI();

			}
		});
	}



	
}//END
